/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hhf.flex.ascreator.patterns;

import hhf.flex.annotations.services.ChainLoad;
import hhf.flex.ascreator.ASClassCreator;
import hhf.flex.ascreator.exceptions.IllegalParameterException;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;

/**
 *
 * @author utilisateur
 */
public class ASChainLoadsPattern {

	private static String getTabs(int tabs) {
		String result = "";
		for (int i = 0; i < tabs; i++) {
			result += "\t";
		}
		return result;
	}

	public static String writeChainLoadFunction(OutputStreamWriter out, ChainLoad chainLoad, Method method, String returnType) throws IOException, IllegalParameterException {

		String body = "";
		boolean goCatch = false;
		String functionName = "chainLoad_";
		functionName += chainLoad.methodClass().toString().split(" ")[1];
		functionName += chainLoad.method();

		String parameter = chainLoad.parameters();

		if ((parameter == null) || (parameter.equals(""))) {
			throw new IllegalParameterException(parameter + " : invalide");
		}
		String cacheService = chainLoad.methodClass().getPackage().getName();
		String classNameBis = chainLoad.methodClass().getSimpleName();
		cacheService += "." + classNameBis.substring(0, 1).toLowerCase() + classNameBis.substring(1);

		cacheService += "." + chainLoad.method();
		String declaration = "var chainLoad:" + cacheService + " = new " + cacheService + "()";

		body += "\t\t\t" + declaration + ";\n";
		String[] hashString = parameter.split("\\.");
		String sendParameters = "";
		Class lastClass = method.getReturnType();
		int indentations = 3;

		String lastVariable = "";

		//TODO voir les autres String qui définissent le retour d'un tableau 
		if ((lastClass.equals(List.class) || (lastClass.equals(Collection.class)) || (lastClass.isArray()))) {

			try {
				String encaps = ASClassCreator.getMethod(method.getDeclaringClass(), method.getName(), method.getParameterTypes()).toGenericString();
				encaps = encaps.split("<")[1].split(">")[0];
				lastClass = Class.forName(encaps);
			} catch (Exception ex) {
				throw new IllegalParameterException(ex.getMessage());
			}

			body += getTabs(indentations);
			body += "for each(var datas_var:Object in datas)\n";
			indentations++;
			lastVariable = "datas_var";
			sendParameters += "datas_var";
		} else {
			lastVariable = "datas";
			sendParameters += "datas";
		}
		int braces = 0;

		for (int i = 1; i < hashString.length; i++) {
			String current = hashString[i];
			Class currentClass = null;
			String genericString = null;
			String subClassString = null;
			boolean inArray = false;

			try {
				if ( //TODO LEN-1 !!!  
						  ASClassCreator.getField(lastClass, current).toGenericString().split(" ")[1].split("<").length != 2) {
					genericString = ASClassCreator.getField(lastClass, current).toGenericString().split(" ")[1].split("<")[0];
					currentClass = Class.forName(genericString);
				} else {
					subClassString = ASClassCreator.getField(lastClass, current).toGenericString().split(" ")[1].split("<")[1].split(">")[0];
					currentClass = Class.forName(subClassString);
					inArray = true;
				}

			} catch (ClassNotFoundException ex) {
				throw new IllegalParameterException("\n" + genericString + " : ClassNotFound");
			} catch (NoSuchFieldException ex) {
				throw new IllegalParameterException("NoSuchFieldException!!!!");
			} catch (NullPointerException ex) {
				throw new IllegalParameterException("NullPointerException ");
			}

			if (inArray) {
				String variable = current + "_var";
				variable = variable.replace('(', '_');
				variable = variable.replace(')', '_');
				functionName += "_" + variable;
				body += getTabs(indentations);
				body += "for each(var " + variable + ":Object in " + lastVariable + "." + current + ") { \n";
				body += getTabs(indentations + 1);
				body += "try {\n\t";
				goCatch = true;
		//		body += getTabs(indentations + 2);
		//		body += "Alert.show(\""+indentations+"\" + \" \"+"+variable+" );\n";
				sendParameters += "." + variable;
				braces++;
				lastVariable = variable;
				indentations++;
				try {
					lastClass = Class.forName(subClassString);
				} catch (ClassNotFoundException ex) {
					throw new IllegalParameterException("\n" + subClassString + " : ClassNotFound");
				}
			} else {
				sendParameters += "." + current;
				String variable = current + "_var";
				variable = variable.replace('(', '_');
				variable = variable.replace(')', '_');
				functionName += "_" + variable;
				lastClass = currentClass;
			}
		}

		body += getTabs(indentations + 2);
		body += "chainLoad.loadInLocaleBase(" + sendParameters + ");\n";
		
		
		if (goCatch) {
		body += getTabs(indentations + 1);
		body += " } catch(e:Object){Alert.show(\"error \"+e);}\n";
		}
		for (int i = braces;i>0 ; i--) {
			body += getTabs(indentations - i);
			body += "}\n";
		}
		body += "\t\t}\n";
		functionName = functionName.replace(" ", "_");
		functionName = functionName.replace(".", "_");
		out.write("\t\tprivate function " + functionName + "(datas: " + returnType + "):void {\n");
		out.write(body);
		return functionName;
	}
}
